package org.example.thread.futuretask.demo2;

import org.junit.Test;

import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @Classname test1
 * @Description 假设现在有一个网页，我们需要下载图片并显示出来给用户看，
 * 最高效率的做法就是每下载完一张图片就显示一张，其它未下载完成的占一个空间等待渲染.
 * 用FutureTask如何实现，我们用一个HashMap来模拟图片，key代表图片，value代表下载的时间(秒).
 * @Date 2020/12/18 9:52 上午
 * @Created by xiangjd
 */
public class test1 {


    /**
     * 这种方法不满足第4张图片先展示出来（第4张图片只需要下载1秒）
     * @throws ExecutionException
     */
    @Test
    public void test1() throws ExecutionException {
        final Map<String, Integer> map = new LinkedHashMap<>();//确保插入有序
        map.put("1.jpg", 5);
        map.put("2.jpg", 3);
        map.put("3.jpg", 7);
        map.put("4.png", 1);

        LinkedBlockingQueue<Future<String>> s = new LinkedBlockingQueue<>();//用于保存Future

        ExecutorService service = Executors.newFixedThreadPool(4);//创建一个线程池
        for (String b : map.keySet()) {//遍历每张图片，并提交任务
            Future<String> future = service.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(map.get(b) * 1000); //模拟下载中
                    return b; //下载完成返回这张图片
                }
            });
            s.add(future);
        }
        //从阻塞队列中取的Future获取结果
        for (int i = 0; i < 4; i++) {
            Future<String> poll = null;
            try {
                poll = s.take();
                System.out.println(poll.get());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        service.shutdown();//关闭线程池
    }

//    @Test
//    public void test2() throws InterruptedException {
//        LinkedBlockingQueue<String> block = new LinkedBlockingQueue<>();//用于保存Future
//        final Map<String, Integer> map = new LinkedHashMap<>();
//        map.put("1.jpg", 5);
//        map.put("2.jpg", 3);
//        map.put("3.jpg", 7);
//        map.put("4.png", 1);
//
//        for (String s : map.keySet()) {
//            new Thread(new QueenFutureTask<String>(new Callable<String>() {
//                @Override
//                public String call() throws Exception {
//                    Thread.sleep(map.get(s) * 1000);
//                    return s;
//                }
//            }) {
//
//            }).start();
//        }
//        for (int i = 0; i < 4; i++) {
//            String take = block.take();
//            System.out.println(take);
//        }
//
//    }


    /**
     * completionServicek可以实现按照图片下载时间从小到大一次排列
     * @throws Exception
     */
    @Test
    public void test3() throws Exception {
        final Map<String, Integer> map = new LinkedHashMap<>();
        map.put("1.jpg", 5);
        map.put("2.jpg", 3);
        map.put("3.jpg", 7);
        map.put("4.png", 1);
        ExecutorService service = Executors.newFixedThreadPool(4);

        //需要传一个线程池
        CompletionService<String> completionService = new ExecutorCompletionService<>(service);

        for (String s : map.keySet()) {
            completionService.submit(new Callable<String>() {
                @Override
                public String call() throws Exception {
                    Thread.sleep(map.get(s) * 1000);
                    return s;
                }
            });
        }

        for (int i = 0; i < map.size(); i++) {
            Future<String> take = completionService.take();
            String s = take.get();
            System.out.println(s);
        }

        service.shutdown();
    }

}


